package fr.upmc.aladyn.transactionables.saveobject;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import fr.upmc.aladyn.transactionables.saveobject.SaveManager;
import fr.upmc.aladyn.transactionables.tests.objects.Point3D;


/**
 * <p>Test class</p>
 * @author Alexis Deluze
 *
 */
public class TestSaveManagerAppelSuccessifFiniParException {
	private Point3D point3d;
	private int xini2;
	private int yini2;
	private int zini2;
	
	@Before
	public void initialise(){
		System.out.println("Debut du Test TestAppelSuccessifFiniParException");
		
		point3d = new Point3D(0, 0, 0);
	}

	
	@After
	public void end(){
		point3d = null;
		SaveManager.getManager().destroy();
		System.out.println("Fin du Test TestAppelSuccessifFiniParException");
	}
	
	@Test
	public void test() {
		SaveManager.getManager().newStackBlock();
		
		SaveManager.getManager().save(point3d);
		point3d.setX(2);
		point3d.setZ(6);

		try{
			methodTransactionnable(false);
		}catch(Exception e){
			assertTrue(false);
		}
		
		assertTrue(7 == point3d.getX());
		assertTrue(7 == point3d.getY());
		assertTrue(7 == point3d.getZ());
		
		try{
			methodTransactionnable(true);
		}catch(Exception e){
			assertTrue(true);
		}
		
		SaveManager.getManager().save(point3d);
		point3d.setY(3);

		System.out.println(point3d);

		assertTrue(7 == point3d.getX());
		assertTrue(3 == point3d.getY());
		assertTrue(7 == point3d.getZ());
	}
	
	
	public void methodWithException() throws Exception{
		System.out.println("Lancement d'une exception.");
		throw new Exception("Lancement d'une exception.");
	}

	public void methodTransactionnable(boolean willFail) throws Exception{	
		SaveManager.getManager().newStackBlock();
		
		xini2 = point3d.getX();
		yini2 = point3d.getY();
		zini2 = point3d.getZ();
		
		try {
			SaveManager.getManager().save(point3d);
			point3d.setX(5);		
			point3d.setY(9);
			point3d.setZ(8);
			
			if(willFail){
				methodWithException();
			}
			
			SaveManager.getManager().save(point3d);
			point3d.setX(7);
			point3d.setY(7);
			point3d.setZ(7);
			
		} catch (Exception e) {
			SaveManager.getManager().restore();
			SaveManager.getManager().pop();

			System.out.println(point3d);
			assertTrue(xini2 == point3d.getX());
			assertTrue(yini2 == point3d.getY());
			assertTrue(zini2 == point3d.getZ());
			
			throw e;
		}
		SaveManager.getManager().pop();
	}
}